package com.xqkj.commons.virtualdb.templates.impl;

import com.xqkj.commons.constant.HandleResultCode;
import com.xqkj.commons.model.HandleResult;
import com.xqkj.commons.model.basicdo.BasicDo;
import com.xqkj.commons.virtualdb.model.*;
import com.xqkj.commons.virtualdb.service.functions.*;
import com.xqkj.commons.virtualdb.templates.UpdateModelToVirtualDb;

import java.util.function.Consumer;
import java.util.function.Function;

/**
 * @author lwt<br>
 * @description <br>
 * @date 2020/1/16
 */
public class DefUpdateModelToVirtualDb<P extends BasicDo> extends BasicUpdateModelToVirtualDb<P>
        implements UpdateModelToVirtualDb<P> {

    private Function<VirtualDbNormalShadingKeysModel,P> shadingKeysQueryModelFunction;
    //
    private Function<P,Integer> updateModelFunction;
    private Function<UnionIdxMappingSvModel,Integer> delOldAndInsertNewUidxMappingFunction;
    private Function<GetByUnionIdxParameterModel,P> getByMainUidxFunction;
    private Function<String,Boolean> lockFunction;
    private Consumer<String> unLockFunction;
    //
    private Function<ParametersWrappedModel<P>,VirtualDbLockInfoModel> lockInfoGetter;
    private Function<VirtualDbLockInfoModel, HandleResult<P>> dbModelGetter;
    private Function<VirtualDbLockInfoModel, VirtualDbLockResultModel> lockAllFunction;
    private Consumer<VirtualDbLockInfoModel> unLockAllFunction;
    private Function<P,HandleResult<Integer>> modelInfoWriter;
    private Function<VirtualDbLockInfoModel,HandleResult<String>> unionTmpMappingWriter;
    //
    private OperateModelToVirtualDbHelper<P> operateModelToVirtualDbHelper;
    //
    private boolean isInit=false;

    public DefUpdateModelToVirtualDb(){

    }

    public void init(){
        if(isInit){
            return;
        }
        lockInfoGetter=new LockInfoGetter<>();
        unionTmpMappingWriter=new UnionTmpMappingWriter(delOldAndInsertNewUidxMappingFunction,null);
        dbModelGetter=new DbModelGetter<>(getByMainUidxFunction,null);
        lockAllFunction=new LockAllFunction(lockFunction);
        unLockAllFunction=new UnLockAllFunction(unLockFunction);
        modelInfoWriter=new ModelInfoWriter<>(updateModelFunction);
        //
        operateModelToVirtualDbHelper=new OperateModelToVirtualDbHelper();
        operateModelToVirtualDbHelper.setDbModelGetter(dbModelGetter);
        operateModelToVirtualDbHelper.setLockAllFunction(lockAllFunction);
        operateModelToVirtualDbHelper.setUnLockAllFunction(unLockAllFunction);
        isInit=true;
    }

    @Override
    public HandleResult<Integer> updateModelWithOutUidx(P model, Long tenantId, String tenantExtCode, VirtualDbAttributeIdxConfigModel attributeIdxConfig) {
        VirtualDbNormalShadingKeysModel shadingKeysModel=new VirtualDbNormalShadingKeysModel();
        shadingKeysModel.setPkId(model.getPkId());
        shadingKeysModel.setTenantId(tenantId);
        P dbModel=shadingKeysQueryModelFunction.apply(shadingKeysModel);
        if(dbModel==null){
            return HandleResult.failed(HandleResultCode.DATA_NOT_EXISTED.getCode(),HandleResultCode.DATA_NOT_EXISTED.getDesc());
        }
        return updateModelAndTryCleanCache(model);
    }

    @Override
    public HandleResult<Integer> updateModelUidxFileds(P model, Long tenantId, String tenantExtCode, VirtualDbAttributeIdxConfigModel attributeIdxConfig) {
        VirtualDbNormalShadingKeysModel shadingKeysModel=new VirtualDbNormalShadingKeysModel();
        shadingKeysModel.setPkId(model.getPkId());
        shadingKeysModel.setTenantId(tenantId);
        P dbModel=shadingKeysQueryModelFunction.apply(shadingKeysModel);
        if(dbModel==null){
            return HandleResult.failed(HandleResultCode.DATA_NOT_EXISTED.getCode(),HandleResultCode.DATA_NOT_EXISTED.getDesc());
        }
        //
        ParametersWrappedModel<P> parametersWrappedModel=new ParametersWrappedModel<>();
        parametersWrappedModel.setParameter(model);
        parametersWrappedModel.setTenantId(tenantId);
        parametersWrappedModel.setTenantExtCode(tenantExtCode);
        //
        VirtualDbLockInfoModel virtualDbLockInfoModel = lockInfoGetter.apply(parametersWrappedModel);
        return operateModelToVirtualDbHelper.lockAddMappingAndExecuteOperation(
                parametersWrappedModel,virtualDbLockInfoModel,
                (parametersWrapped,virtualDbLockInfo)->
                        handleUnionTmpMapping(parametersWrapped,virtualDbLockInfo),
                (parametersWrapped)->
                        doUpdateModel(parametersWrapped.getParameter()));
    }

    @Override
    protected HandleResult<Integer> doUpdateModel(P model) {
        return modelInfoWriter.apply(model);
    }

    protected HandleResult<String> handleUnionTmpMapping(ParametersWrappedModel<P> parametersWrapped, VirtualDbLockInfoModel virtualDbLockInfoModel) {
        return unionTmpMappingWriter.apply(virtualDbLockInfoModel);
    }

    //////////////////////////////////

    public void setShadingKeysQueryModelFunction(Function<VirtualDbNormalShadingKeysModel, P> shadingKeysQueryModelFunction) {
        this.shadingKeysQueryModelFunction = shadingKeysQueryModelFunction;
    }

    public void setUpdateModelFunction(Function<P, Integer> updateModelFunction) {
        this.updateModelFunction = updateModelFunction;
    }

    public void setDelOldAndInsertNewUidxMappingFunction(Function<UnionIdxMappingSvModel, Integer> delOldAndInsertNewUidxMappingFunction) {
        this.delOldAndInsertNewUidxMappingFunction = delOldAndInsertNewUidxMappingFunction;
    }

    public void setGetByMainUidxFunction(Function<GetByUnionIdxParameterModel, P> getByMainUidxFunction) {
        this.getByMainUidxFunction = getByMainUidxFunction;
    }

    public void setLockFunction(Function<String, Boolean> lockFunction) {
        this.lockFunction = lockFunction;
    }

    public void setUnLockFunction(Consumer<String> unLockFunction) {
        this.unLockFunction = unLockFunction;
    }


}
